package com.googlecode.continuity.plugin.svnbrowser.server.rpc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNLock;
import org.tmatesoft.svn.core.SVNNodeKind;
import com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNException;
import com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNRPC;
import com.googlecode.continuity.plugin.svnbrowser.client.SVNRepositoryHandle;
import com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNDirEntryWrapper;
import com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNLockWrapper;
import com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNNodeKindWrapper;
import com.googlecode.continuity.plugin.svnbrowser.server.service.ReadSVNService;
import com.googlecode.continuity.plugin.svnbrowser.server.service.ReadSVNServiceSVNKit;

/**
 * ReadSVNRPCImpl
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class ReadSVNRPCImpl implements ReadSVNRPC {
// ------------------------------ FIELDS ------------------------------

  private ReadSVNService readSVNService;

// --------------------- GETTER / SETTER METHODS ---------------------

  public void setReadSVNService(ReadSVNServiceSVNKit readSVNService) {
    this.readSVNService = readSVNService;
  }

// ------------------------ INTERFACE METHODS ------------------------

// --------------------- Interface ReadSVNRPC ---------------------

  public SVNRepositoryHandle connect(String url, String username, String password) throws ReadSVNException {
    return readSVNService.connect(url, username, password);
  }

  /**
   * @param directoryPath
   * @return
   * @throws com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNException
   *
   * @gwt.typeArgs java.util.List<com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNDirEntryWrapper>
   */
  public List getDirectoryContents(SVNRepositoryHandle handle, String directoryPath) throws ReadSVNException {
    // translate to serializable entities
    List contents = readSVNService.getDirectoryContents(handle, directoryPath);
    List ret = new ArrayList();
    for (Object object : contents) {
      SVNDirEntry entry = (SVNDirEntry) object;
      SVNDirEntryWrapper wrapper = new SVNDirEntryWrapper(entry.getName(), getSVNNodeKind(entry.getKind()),
          entry.getSize(), entry.hasProperties(), entry.getRevision(), new Date(entry.getDate().getTime()),
          entry.getAuthor(), entry.getURL().toString());
      if (entry.getCommitMessage() != null) {
        wrapper.setCommitMessage(entry.getCommitMessage());
      }
      if (entry.getLock() != null) {
        SVNLock lock = entry.getLock();
        wrapper.setLock(new SVNLockWrapper(lock.getPath(), lock.getID(), lock.getOwner(), lock.getComment(),
            new Date(lock.getCreationDate().getTime()), new Date(lock.getExpirationDate().getTime())));
      }
      ret.add(wrapper);
    }
    return ret;
  }

  /**
   * @param directoryPath
   * @param revision
   * @return
   * @throws com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNException
   *
   * @gwt.typeArgs java.util.List<com.googlecode.continuity.plugin.svnbrowser.client.wrapper.SVNDirEntryWrapper>
   */
  public List getDirectoryContents(SVNRepositoryHandle handle, String directoryPath, long revision)
      throws ReadSVNException {
    List contents = readSVNService.getDirectoryContents(handle, directoryPath, revision);
    List ret = new ArrayList();
    for (Object object : contents) {
      SVNDirEntry entry = (SVNDirEntry) object;
      SVNDirEntryWrapper wrapper = new SVNDirEntryWrapper(entry.getName(), getSVNNodeKind(entry.getKind()),
          entry.getSize(), entry.hasProperties(), entry.getRevision(), new Date(entry.getDate().getTime()),
          entry.getAuthor(), entry.getURL().toString());
      if (entry.getCommitMessage() != null) {
        wrapper.setCommitMessage(entry.getCommitMessage());
      }
      if (entry.getLock() != null) {
        SVNLock lock = entry.getLock();
        wrapper.setLock(new SVNLockWrapper(lock.getPath(), lock.getID(), lock.getOwner(), lock.getComment(),
            new Date(lock.getCreationDate().getTime()), new Date(lock.getExpirationDate().getTime())));
      }
      ret.add(wrapper);
    }
    return ret;
  }

  /**
   * @param filePath
   * @return
   * @throws com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNException
   *
   */
  public String getTextFileContents(SVNRepositoryHandle handle, String filePath) throws ReadSVNException {
    return readSVNService.getTextFileContents(handle, filePath);
  }

  /**
   * @param filePath
   * @param revision
   * @return
   * @throws com.googlecode.continuity.plugin.svnbrowser.client.ReadSVNException
   *
   */
  public String getTextFileContents(SVNRepositoryHandle handle, String filePath, long revision)
      throws ReadSVNException {
    return readSVNService.getTextFileContents(handle, filePath, revision);
  }

// -------------------------- OTHER METHODS --------------------------

  private int getSVNNodeKind(SVNNodeKind kind) {
    if (kind == SVNNodeKind.DIR) {
      return SVNNodeKindWrapper.DIR;
    }
    if (kind == SVNNodeKind.FILE) {
      return SVNNodeKindWrapper.FILE;
    }
    if (kind == SVNNodeKind.NONE) {
      return SVNNodeKindWrapper.NONE;
    }
    return SVNNodeKindWrapper.UNKNOWN;
  }
}
